<!DOCTYPE html>
<html>

<head><meta name="generator" content="Hexo 3.9.0">
  
  <title>OpenCV2.4.13.6在Android上的采坑（native扩展nonfree） - zzzz1997博客</title>
  <meta charset="UTF-8">
  <meta name="description" content>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  

  <link rel="shortcut icon" href="/favicon.ico" type="image/png">
  <meta name="description" content="最近在做一个小组作业，利用SUFT实现图像拼接。采用的是OpenCV2.4.13.6，而在搭建的时候发现Android pack中并没有nonfree文件夹（包括nonfree/features2d.hpp头文件），而libs/**abi/文件夹中也没有相关的libnonfree.so文件，所以并不能使用SUFT。">
<meta name="keywords" content="OpenCV,Android">
<meta property="og:type" content="article">
<meta property="og:title" content="OpenCV2.4.13.6在Android上的采坑（native扩展nonfree）">
<meta property="og:url" content="https://zzzz1997.github.io/2019/09/11/OpenCV2-4-13-6/index.html">
<meta property="og:site_name" content="zzzz1997博客">
<meta property="og:description" content="最近在做一个小组作业，利用SUFT实现图像拼接。采用的是OpenCV2.4.13.6，而在搭建的时候发现Android pack中并没有nonfree文件夹（包括nonfree/features2d.hpp头文件），而libs/**abi/文件夹中也没有相关的libnonfree.so文件，所以并不能使用SUFT。">
<meta property="og:locale" content="zh">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/android-sdk.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/vc14.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/jni.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/ndk-build-error.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/ndk-build-success.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree_demo_src.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree_demo.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/armeabi.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/application.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/activity.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/so.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/add_library.png">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/image.jpg">
<meta property="og:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/image_result.jpg">
<meta property="og:updated_time" content="2019-09-12T02:27:02.963Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="OpenCV2.4.13.6在Android上的采坑（native扩展nonfree）">
<meta name="twitter:description" content="最近在做一个小组作业，利用SUFT实现图像拼接。采用的是OpenCV2.4.13.6，而在搭建的时候发现Android pack中并没有nonfree文件夹（包括nonfree/features2d.hpp头文件），而libs/**abi/文件夹中也没有相关的libnonfree.so文件，所以并不能使用SUFT。">
<meta name="twitter:image" content="http://qiniu.zzzz1997.com/opencv-nonfree/android-sdk.png">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/mdui@0.4.3/dist/css/mdui.min.css">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/highlight.js@9.15.8/styles/atom-one-dark.css">
   
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.css">
  
  
    <link rel="stylesheet" href="//at.alicdn.com/t/font_1408556_n2qarh8jxce.css">
  
  <link rel="stylesheet" href="//at.alicdn.com/t/font_1038733_0xvrvpg9c0r.css">
  <link rel="stylesheet" href="/css/style.css?v=1569304942397">
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome/css/font-awesome.min.css">
</head>

<body class="mdui-drawer-body-left">
  
  <div id="nexmoe-background">
    <div class="nexmoe-bg" style="background-image: url(http://qiniu.zzzz1997.com/7f9b18d65986d68f808cfbaca4583d81.jpg)"></div>
    <div class="mdui-appbar mdui-shadow-0">
      <div class="mdui-toolbar">
        <a mdui-drawer="{target: '#drawer', swipe: true}" title="menu" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">menu</i></a>
        <div class="mdui-toolbar-spacer"></div>
        <!--<a href="javascript:;" class="mdui-btn mdui-btn-icon"><i class="mdui-icon material-icons">search</i></a>-->
        <a href="/" title="zzzz1997" class="mdui-btn mdui-btn-icon"><img src="/images/avatar.jpg"></a>
       </div>
    </div>
  </div>
  <div id="nexmoe-header">
      <div class="nexmoe-drawer mdui-drawer" id="drawer">
    <div class="nexmoe-avatar mdui-ripple">
        <a href="/" title="zzzz1997">
            <img src="/images/avatar.jpg" alt="zzzz1997">
        </a>
    </div>
    <div class="nexmoe-count">
        <div><span>Articles</span>6</div>
        <div><span>Tags</span>6</div>
        <div><span>Categories</span>2</div>
    </div>
    <ul class="nexmoe-list mdui-list" mdui-collapse="{accordion: true}">
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/" title="回到首页">
            <i class="mdui-list-item-icon nexmoefont icon-home"></i>
            <div class="mdui-list-item-content">
                回到首页
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/miao" title="喵">
            <i class="mdui-list-item-icon nexmoefont icon-maomi"></i>
            <div class="mdui-list-item-content">
                喵
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/doraemon" title="Doraemon">
            <i class="mdui-list-item-icon nexmoefont icon-lingdang"></i>
            <div class="mdui-list-item-content">
                Doraemon
            </div>
        </a>
        
        <a class="nexmoe-list-item mdui-list-item mdui-ripple" href="/about" title="关于博客">
            <i class="mdui-list-item-icon nexmoefont icon-info-circle"></i>
            <div class="mdui-list-item-content">
                关于博客
            </div>
        </a>
        
    </ul>
    <aside id="nexmoe-sidebar">
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">Social</h3>
    <div class="nexmoe-widget nexmoe-social">
        <a class="mdui-ripple" href="https://github.com/zzzz1997/" target="_blank" mdui-tooltip="{content: 'GitHub'}" style="color: rgb(25, 23, 23);background-color: rgba(25, 23, 23, .15);">
            <i class="nexmoefont icon-github"></i>
        </a>
    </div>
</div>
  
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">Categories</h3>
    <div class="nexmoe-widget">

      <ul class="category-list">

        


        

        

        <li class="category-list-item">
          <a class="category-list-link" href="/categories/喜欢/">喜欢</a>
          <span class="category-list-count">2</span>
        </li>

        

        <li class="category-list-item">
          <a class="category-list-link" href="/categories/技术/">技术</a>
          <span class="category-list-count">3</span>
        </li>

        
      </ul>

    </div>
  </div>


  
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">Tagcloud</h3>
    <div id="randomtagcloud" class="nexmoe-widget tagcloud">
      <a href="/tags/Android/" style="font-size: 10px;">Android</a> <a href="/tags/OpenCV/" style="font-size: 10px;">OpenCV</a> <a href="/tags/dart/" style="font-size: 10px;">dart</a> <a href="/tags/doraemon/" style="font-size: 10px;">doraemon</a> <a href="/tags/kotlin/" style="font-size: 10px;">kotlin</a> <a href="/tags/miao/" style="font-size: 10px;">miao</a>
    </div>
    
  </div>

  
  
  <div class="nexmoe-widget-wrap">
    <h3 class="nexmoe-widget-title">Archive</h3>
    <div class="nexmoe-widget">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/09/">September 2019</a></li></ul>
    </div>
  </div>


  
</aside>
    <div class="nexmoe-copyright">
        &copy; 2019 zzzz1997
        Powered by <a href="http://hexo.io/" target="_blank">Hexo</a>
        & <a href="https://nexmoe.com/hexo-theme-nexmoe.html" target="_blank">Nexmoe</a>
    </div>
</div><!-- .nexmoe-drawer -->
  </div>
  <div id="nexmoe-content">
    <div class="nexmoe-primary">
        <div class="nexmoe-post">
    <div class="nexmoe-post-cover"> 
        
        <img src="http://qiniu.zzzz1997.com/opencv-nonfree/image_result.jpg">
        
        <h1>OpenCV2.4.13.6在Android上的采坑（native扩展nonfree）</h1>
    </div>
  <div class="nexmoe-post-meta">
    <a><i class="nexmoefont icon-calendar-fill"></i>2019年09月11日</a>
    <a><i class="nexmoefont icon-areachart"></i>1.6k 字</a>
    <a><i class="nexmoefont icon-time-circle-fill"></i>大概 8 分钟</a>
    
      <a class="nexmoefont icon-appstore-fill -link" href="/categories/技术/">技术</a>
    
    
      <a class="nexmoefont icon-tag-fill -link" href="/tags/Android/">Android</a> <a class="nexmoefont icon-tag-fill -link" href="/tags/OpenCV/">OpenCV</a>
    
  </div>
  <article>
    <p>最近在做一个小组作业，利用SUFT实现图像拼接。采用的是<a href="https://opencv.org/releases.html" target="_blank" rel="noopener">OpenCV2.4.13.6</a>，而在搭建的时候发现Android pack中并没有<code>nonfree</code>文件夹（包括<code>nonfree/features2d.hpp</code>头文件），而<code>libs/**abi/</code>文件夹中也没有相关的<code>libnonfree.so</code>文件，所以并不能使用SUFT。</p>
<a id="more"></a>

<p>所以只好利用NDK自己构建.so文件。参考<a href="https://github.com/bkornel/opencv_android_nonfree" target="_blank" rel="noopener">前辈的使用方法</a></p>
<p><strong>使用工具：</strong></p>
<ul>
<li>ndk-bundle工具</li>
<li>opencv-2.4.13.6-android-sdk</li>
<li>opencv-2.4.13.6-vc14（注意版本必须和android-sdk相同）</li>
</ul>
<h2 id="开始构建libnonfree-so文件"><a href="#开始构建libnonfree-so文件" class="headerlink" title="开始构建libnonfree.so文件"></a>开始构建libnonfree.so文件</h2><p>1.首先解压下载的opencv-2.4.13.6-android-sdk.zip文件，注意文件目录不能含有中文（否则后面.mk可能会编码错乱），如：F:\opencv-2.4.13.6-android-sdk</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/android-sdk.png">

<p>2.安装opencv-2.4.13.6-vc14.exe，得到如下文件夹</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/vc14.png">

<p>3.打开目录<code>sources/modules/nonfree/include/opencv2</code>，将其中的<code>nonfree</code>文件夹复制到<code>F:/opencv-2.4.13.6-android-sdk/OpenCV-android-sdk/sdk/native/jni/include/opencv2</code>文件夹中</p>
<p>4.在任意位置新建一个<code>libnonfree</code>文件夹，并在其中新建<code>jni</code>文件夹，例如我新建在<code>F:/opencv-2.4.13.6-android-sdk/OpenCV-android-sdk/sdk/native/jni/include/libnonfree</code>处</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/jni.png">

<p>再将opencv-2.4.13.6-vc14文件夹<code>sources/modules/nonfree/src</code>位置的<code>nonfree_init.cpp</code>，<code>precomp.hpp</code>，<code>sift.cpp</code>和<code>surf.cpp</code>四个文件复制到之前新建的<code>libnonfree/jni</code>文件夹中。</p>
<p>5.在<code>libnonfree/jni</code>文件夹中新建两个文件<code>Android.mk</code>，<code>Application.mk</code>，此时你的文件目录应该是这样</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree.png">

<p>编辑<code>Android.mk</code>文件：</p>
<pre><code class="mk">LOCAL_PATH  := $(call my-dir)
OPENCV_PATH := F:\opencv-2.4.13.6-android-sdk\OpenCV-android-sdk\sdk\native\jni

include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES := on
OPENCV_CAMERA_MODULES  := off
include $(OPENCV_PATH)/OpenCV.mk

LOCAL_C_INCLUDES :=             \
    $(LOCAL_PATH)               \
    $(OPENCV_PATH)/include

LOCAL_SRC_FILES :=              \
    nonfree_init.cpp            \
    sift.cpp                    \
    surf.cpp

LOCAL_MODULE := nonfree
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS := -llog -ldl

include $(BUILD_SHARED_LIBRARY)</code></pre>
<p>编辑<code>Application.mk</code>文件：</p>
<pre><code class="mk">APP_STL := gnustl_shared
APP_CPPFLAGS := -std=c++11 -frtti -fexceptions
APP_ABI := armeabi,armeabi-v7a,mips,x86
APP_PLATFORM := android-21</code></pre>
<p>6.完成上面的步骤后，就可以使用命令行工具进入<code>F:/opencv-2.4.13.6-android-sdk/OpenCV-android-sdk/sdk/native/jni/include/libnonfree</code>文件夹，再使用<code>ndk-build</code>命令，如遇到“‘ndk-build’不是内部或外部命令，也不是可运行的程序或批处理文件”，请检查下载ndk-bundle工具并在环境变量中配置好ndk-build</p>
<p>此时执行，会下列一系类报错，例如</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/ndk-build-error.png">

<blockquote>
<p>一次性解决方案：<br>第一步，打开<code>precomp.hpp</code>注释掉第46行<code>#include &quot;cvconfig.h&quot;</code>和第66行<code>#  include &quot;opencv2/ocl/private/util.hpp&quot;</code>；第二步，打开<code>nonfree_init.cpp</code>文件，注释掉第66到第77行，<code>OPENCV_OCL</code>部分，完成</p>
</blockquote>
<p>再次执行‘ndk-build’，通过！</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/ndk-build-success.png">

<p>此时你的<code>libnonfree</code>文件夹里多了两个文件夹<code>libs</code>，<code>obj</code>，其中<code>libs</code>里面的全部.so文件就是我们需要的文件啦！</p>
<h2 id="开始使用SUFT"><a href="#开始使用SUFT" class="headerlink" title="开始使用SUFT"></a>开始使用SUFT</h2><p>1.在任意位置新建一个<code>libnonfree_demo</code>文件夹，并在其中新建<code>jni</code>文件夹，例如我建立在<code>libnonfree</code>文件夹同级目处</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree_demo_src.png">

<p>以armeabi架构为例，将上面的<code>libnonfree/libs/armeabi</code>中所有的.so文件拷贝到<code>jni</code>文件中</p>
<p>2.在文件夹中新建一个.cpp文件，例如<code>test.cpp</code></p>
<pre><code class="c">#include &lt;jni.h&gt;
#include &lt;android/log.h&gt;

#include &lt;opencv2/core/core.hpp&gt;
#include &lt;opencv2/highgui/highgui.hpp&gt;
#include &lt;opencv2/nonfree/features2d.hpp&gt;
#include &lt;opencv2/nonfree/nonfree.hpp&gt;
#include &lt;iostream&gt;

using namespace cv;
using namespace std;

#define  LOG_TAG    &quot;nonfree_demo&quot;
#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)

int run_demo();

extern &quot;C&quot; {
JNIEXPORT void JNICALL Java_com_zzapp_nonfree_MainActivity_runDemo(JNIEnv * env, jobject obj);
};

JNIEXPORT void JNICALL Java_com_zzapp_nonfree_MainActivity_runDemo(JNIEnv * env, jobject obj)
{
    LOGI( &quot;开始demo\n&quot;);
    run_demo();
    LOGI( &quot;结束demo\n&quot;);
}

int run_demo()
{
    // 输入输出图片地址
    const char * imgInFile = &quot;/sdcard/nonfree/image.jpg&quot;;
    const char * imgOutFile = &quot;/sdcard/nonfree/image_result.jpg&quot;;

    Mat image;
    image = imread(imgInFile, CV_LOAD_IMAGE_COLOR);
    if(! image.data )
    {
        LOGI(&quot;图片不存在\n&quot;);
        return -1;
    }

    vector&lt;KeyPoint&gt; keypoints;
    Mat descriptors;


    // 计算特征描述
    SiftFeatureDetector detector;
    LOGI(&quot;检测到%d个特征点\n&quot;, (int) keypoints.size());
    detector.detect(image, keypoints);
    LOGI(&quot;计算特征描述\n&quot;);
    detector.compute(image,keypoints, descriptors);

    // 存储特征描述
    FileStorage fs;
    LOGI(&quot;以写入方式打开文件\n&quot;);
    fs.open(&quot;descriptors.des&quot;, FileStorage::WRITE);
    LOGI(&quot;写入文件\n&quot;);
    fs &lt;&lt; &quot;descriptors&quot; &lt;&lt; descriptors;
    LOGI(&quot;释放文件\n&quot;);
    fs.release();

    // 显示图片关键点
    Mat outputImg;
    Scalar keypointColor = Scalar(255, 0, 0);
    LOGI(&quot;绘制图片关键点\n&quot;);
    drawKeypoints(image, keypoints, outputImg, keypointColor, DrawMatchesFlags::DRAW_RICH_KEYPOINTS);

    LOGI(&quot;存储生成图片\n&quot;);
    imwrite(imgOutFile, outputImg);

    LOGI(&quot;完成\n&quot;);
    return 0;
}</code></pre>
<p><strong>注意其中的方法名<code>Java_com_zzapp_nonfree_MainActivity_runDemo</code>，你需要将其中的<code>com_zzapp_nonfree_MainActivity</code>更改为你的包名加上使用方法的Activity名（包名在后面的使用中应用到，应提前想好）</strong></p>
<p>3.在<code>libnonfree_demo/jni</code>文件夹中新建两个文件<code>Android.mk</code>，<code>Application.mk</code>，此时你的文件目录应该是这样</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/libnonfree_demo.png">

<p>编辑<code>Android.mk</code>文件：</p>
<pre><code class="mk">LOCAL_PATH  := $(call my-dir)
OPENCV_PATH := F:\opencv-2.4.13.6-android-sdk\OpenCV-android-sdk\sdk\native\jni

include $(CLEAR_VARS)
LOCAL_MODULE     := nonfree
LOCAL_SRC_FILES  := libnonfree.so
include $(PREBUILT_SHARED_LIBRARY)

include $(CLEAR_VARS)
OPENCV_INSTALL_MODULES := on
OPENCV_CAMERA_MODULES  := off
include $(OPENCV_PATH)/OpenCV.mk

LOCAL_C_INCLUDES :=             \
    $(LOCAL_PATH)               \
    $(OPENCV_PATH)/include

LOCAL_SRC_FILES :=              \
    test.cpp

LOCAL_MODULE := nonfree_demo
LOCAL_CFLAGS := -Werror -O3 -ffast-math
LOCAL_LDLIBS := -llog -ldl
LOCAL_SHARED_LIBRARIES += nonfree

include $(BUILD_SHARED_LIBRARY)</code></pre>
<p>编辑<code>Application.mk</code>文件：</p>
<pre><code class="mk">APP_STL := gnustl_shared
APP_CPPFLAGS := -std=c++11 -frtti -fexceptions
APP_ABI := armeabi
APP_PLATFORM := android-21</code></pre>
<p>4.同上，使用命令行工具进入<code>F:/opencv-2.4.13.6-android-sdk/OpenCV-android-sdk/sdk/native/jni/include/libnonfree_demo</code>文件夹，再使用<code>ndk-build</code>命令，成功后，在<code>libnonfree_demo/libs/armeabi</code>里生成了几个.so文件，包括一个<code>libnonfree_demo.so</code>文件</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/armeabi.png">

<p>此时自己的.so文件已生成完毕，即可使用啦！</p>
<h2 id="Android使用-so文件"><a href="#Android使用-so文件" class="headerlink" title="Android使用.so文件"></a>Android使用.so文件</h2><p>1.新建项目，对于我们的上面的.so文件，我们新建一个项目，要和上面<code>test.cpp</code>文件方法<code>Java_com_zzapp_nonfree_MainActivity_runDemo</code>中一致</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/application.png">

<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/activity.png">

<p>2.使用.so有两种方法，在<code>build.gradle</code>文件中添加和制作.jar文件添加，这里我更偏向于后者。所以来制作.jar文件。</p>
<p>新建<code>lib</code>文件夹（注意是“lib”，而不是“libs”），在其中新建一个文件夹<code>armeabi</code>，将<code>libnonfree_demo/libs/armeabi</code>中的所有.so文件拷贝到<code>armeabi</code>文件夹中。以zip方式压缩<code>lib</code>文件夹，并重命名，改为.jar后缀名，例如<code>so.jar</code></p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/so.png">

<p>3.将<code>so.jar</code>文件拷贝到项目的<code>libs</code>下，右键选择<code>Add As Library...</code>作为库添加到项目。</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/add_library.png">

<p>4.修改<code>MainActivity</code>文件</p>
<pre><code class="kotlin">package com.zzapp.nonfree

import android.support.v7.app.AppCompatActivity
import android.os.Bundle

/**
 * Project Nonfree
 * Date 2018/4/25
 *
 * 主活动
 *
 * @author zzzz
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        // 使用方法
        runDemo()
    }

    // 库里面的方法
    external fun runDemo()

    companion object {
        init {
            // 加载.so库文件
            System.loadLibrary(&quot;nonfree_demo&quot;)
        }
    }
}</code></pre>
<p>5.构建前的最后一步，添加权限。因为在<code>test.cpp</code>中，我们有读写外部文件的操作，所以应在<code>AndroidManifest.xml</code>文件中添加两条权限</p>
<pre><code class="xml">&lt;uses-permission android:name=&quot;android.permission.READ_EXTERNAL_STORAGE&quot;/&gt;
&lt;uses-permission android:name=&quot;android.permission.WRITE_EXTERNAL_STORAGE&quot;/&gt;</code></pre>
<p>在手机<code>/sdcard/nonfree</code>目录下新建文件<code>image.jpg</code>，打包运行应用。成功！！</p>
<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/image.jpg">

<img class="img-fluid" src="http://qiniu.zzzz1997.com/opencv-nonfree/image_result.jpg">

  </article>
  
    
<div class="nexmoe-post-copyright">
<i class="mdui-list-item-icon nexmoefont icon-info-circle"></i>
<strong>Author：</strong>zzzz1997<br>
<strong>Link：</strong><a href="https://zzzz1997.github.io/2019/09/11/OpenCV2-4-13-6/" title="https://zzzz1997.github.io/2019/09/11/OpenCV2-4-13-6/" target="_blank" rel="noopener">https://zzzz1997.github.io/2019/09/11/OpenCV2-4-13-6/</a><br>

  <strong>版权声明：</strong>本文采用 <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/cn/deed.zh" target="_blank">CC BY-NC-SA 3.0 CN</a> 协议进行许可

</div>


  
  <section class="nexmoe-comment">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/gitalk@1.5.0/dist/gitalk.min.css">
<div id="gitalk"></div>
<script src="https://cdn.jsdelivr.net/npm/gitalk@1.5.0/dist/gitalk.min.js"></script>
<script type="text/javascript">
    var gitalk = new Gitalk({
        clientID: 'e82953329a9ceaa29251',
        clientSecret: 'c5158215bcc0ef469e83844c5f312a9a54cc00d2',
        id: window.location.pathname,
        repo: 'zzzz1997.github.io',
        owner: 'zzzz1997',
        admin: 'zzzz1997'
    })
    gitalk.render('gitalk')
</script>
</section>
</div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/mdui@0.4.3/dist/js/mdui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jquery@3.4.1/dist/jquery.min.js"></script>
 
    <script src="https://cdn.jsdelivr.net/gh/fancyapps/fancybox@3.5.7/dist/jquery.fancybox.min.js"></script>


 
    <script src="https://cdn.jsdelivr.net/npm/smoothscroll-for-websites@1.4.9/SmoothScroll.min.js"></script>


<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.15.8/build/highlight.min.js"></script>
<script>hljs.initHighlightingOnLoad();</script>

<script src="/js/app.js?v=1569304942418"></script>
<script src="https://cdn.jsdelivr.net/npm/lazysizes@5.1.0/lazysizes.min.js"></script>


    <script type="text/javascript" src="https://cdn.jsdelivr.net/gh/xtaodada/xtaodada.github.io@0.0.2/copy.js"></script>

<script src="https://cdn.jsdelivr.net/gh/zzzz1997/live2d-widget/autoload.js"></script>
  





    <!-- baidu Analytics -->
<script>
    var _hmt = _hmt || [];
    (function() {var hm = document.createElement('script');
    hm.src = 'https://hm.baidu.com/hm.js?09b71f96f7f5fb5e243895d2f1ac0b6b';
    var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(hm, s);
    })();
</script>

<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginModelPath":"assets/","model":{"jsonPath":"/live2dw/assets/tororo.model.json"},"display":{"position":"right","width":150,"height":300},"mobile":{"show":false},"log":false,"pluginJsPath":"lib/","pluginRootPath":"live2dw/","tagMode":false});</script></body>

</html>
